home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / dt / spinner.zip / SPINPLT.C < prev    next >
C/C++ Source or Header  |  1992-05-20  |  6KB  |  235 lines

  1. //
  2. // SPINPLT - spinning rainbow SPX plotting functions
  3. //
  4. // Version 1.0 10/04/91 Copyright (C) 1991 Lantern Corp.
  5. // Author: Edward Hutchins
  6. // Revisions:
  7. //
  8.  
  9. #include "spinner.h"
  10.  
  11. //
  12. // defines
  13. //
  14.  
  15. #define p1  Pt[0]
  16. #define x1  (Pt[0].x)
  17. #define y1  (Pt[0].y)
  18. #define p2  Pt[1]
  19. #define x2  (Pt[1].x)
  20. #define y2  (Pt[1].y)
  21. #define p2o Pt[2]
  22. #define x2o (Pt[2].x)
  23. #define y2o (Pt[2].y)
  24. #define p1o Pt[3]
  25. #define x1o (Pt[3].x)
  26. #define y1o (Pt[3].y)
  27. #define nR  rgbC[0]
  28. #define nG  rgbC[1]
  29. #define nB  rgbC[2]
  30. #define nRd rgbCd[0]
  31. #define nGd rgbCd[1]
  32. #define nBd rgbCd[2]
  33.  
  34. #define newd() ((arand( 10 )) + 3)
  35. #define negd(d) ((d)=(((d)<0) ? newd():-newd()))
  36. #define randsgn() (arand( 2 ) ? 1 : -1)
  37. #define randpos(d) (arand( (d) - 40 ) + 20)
  38. #define randcolor() arand(256)
  39.  
  40. //
  41. // imports
  42. //
  43.  
  44. IMPORT HANDLE       hLibInst FROM( spinner.c );
  45. IMPORT INT          nColorCnt FROM( spinner.c );
  46. IMPORT BOOL         bEnabled FROM( spinner.c );
  47. IMPORT TRI          triBlank FROM( spinner.c );
  48. IMPORT TRI          triSpin FROM( spinner.c );
  49. IMPORT TRI          triSolid FROM( spinner.c );
  50.  
  51. //
  52. // locals
  53. //
  54.  
  55. LOCAL DWORD         dwSeed;
  56.  
  57. //
  58. // arand - pseudorandom number from 0 to x-1
  59. //
  60.  
  61. INT NEAR PASCAL arand( INT x )
  62. {
  63.     dwSeed = dwSeed * 0x343fd + 0x269ec3;
  64.     return( (INT)(((dwSeed >> 16) & 0x7fff) * x >> 15) );
  65. }
  66.  
  67. //
  68. // Tri - convert a tri-state into a boolean (unset == random)
  69. //
  70.  
  71. BOOL NEAR PASCAL Tri( TRI tri )
  72. {
  73.     switch (tri)
  74.     {
  75.     case TRI_FALSE:
  76.         return( FALSE );
  77.     case TRI_TRUE:
  78.         return( TRUE );
  79.     default:
  80.         return( (BOOL)arand( 2 ) );
  81.     }
  82. }
  83.  
  84. //
  85. // AllocPalette - allocate the logical palette
  86. //
  87.  
  88. HPALETTE NEAR PASCAL AllocPalette( INT nSize )
  89. {
  90.     NPLOGPALETTE    npLogPalette;
  91.     HPALETTE        hPalette;
  92.     INT             t;
  93.  
  94.     npLogPalette = (NPLOGPALETTE)LocalAlloc( LPTR, sizeof(LOGPALETTE) +
  95.                     sizeof(PALETTEENTRY) * nSize );
  96.     if (!npLogPalette) return( FALSE );
  97.     npLogPalette->palVersion = 0x0300;
  98.     npLogPalette->palNumEntries = nSize;
  99.  
  100.     for (t = 0; t < nSize; ++t)
  101.     {
  102.         npLogPalette->palPalEntry[t].peRed =
  103.         npLogPalette->palPalEntry[t].peGreen =
  104.         npLogPalette->palPalEntry[t].peBlue = (BYTE)((t * 256) / nSize);
  105.         npLogPalette->palPalEntry[t].peFlags = PC_RESERVED;
  106.     }
  107.  
  108.     hPalette = CreatePalette( npLogPalette );
  109.     LocalFree( (HANDLE)npLogPalette );
  110.     return( hPalette );
  111. }
  112.  
  113. //
  114. // SaverDraw - the main drawing routine
  115. //
  116.  
  117. VOID FAR PASCAL EXPORT SaverDraw( HWND hwnd, HDC hdc, HANDLE hinst,
  118.                                   BOOL (FAR PASCAL *yieldproc)( VOID ) )
  119. {
  120.     INT             xClient, yClient;
  121.     INT             x1d, y1d, x2d, y2d;
  122.     POINT           Pt[4];
  123.     INT             nCurPalEntry;
  124.     INT             rgbC[3], rgbCd[3];
  125.     HPALETTE        hAppPalette, hOldPalette;
  126.     BOOL            bSpin;
  127.     BOOL            bSolid;
  128.     RECT            rect;
  129.  
  130.     dwSeed += GetTickCount();
  131.  
  132.     GetWindowRect( hwnd, &rect );
  133.     xClient = rect.right - rect.left;
  134.     yClient = rect.bottom - rect.top;
  135.  
  136.     if (Tri( triBlank )) FillRect( hdc, &rect, GetStockObject( BLACK_BRUSH ) );
  137.     bSpin = Tri( triSpin );
  138.     bSolid = Tri( triSolid );
  139.  
  140.     hAppPalette = AllocPalette( nColorCnt );
  141.     hOldPalette = SelectPalette( hdc, hAppPalette, FALSE );
  142.     nCurPalEntry = 0;
  143.  
  144.     x1 = randpos( xClient ); x1d = newd() * randsgn();
  145.     x2 = randpos( xClient ); x2d = newd() * randsgn();
  146.     y1 = randpos( yClient ); y1d = newd() * randsgn();
  147.     y2 = randpos( yClient ); y2d = newd() * randsgn();
  148.  
  149.     nR = randcolor(); nRd = newd() * randsgn();
  150.     nG = randcolor(); nGd = newd() * randsgn();
  151.     nB = randcolor(); nBd = newd() * randsgn();
  152.  
  153.     while ((*yieldproc)())
  154.     {
  155.         INT             t;
  156.         PALETTEENTRY    PalEntry;
  157.  
  158.         // save the old coordinates
  159.         p1o = p1; p2o = p2;
  160.  
  161.         // advance the points
  162.         x1 += x1d; y1 += y1d;
  163.         x2 += x2d; y2 += y2d;
  164.  
  165.         // check the bounds
  166.         if (x1 < 0 || x1 > xClient) { x1 -= x1d; negd( x1d ); x1 += x1d; }
  167.         if (x2 < 0 || x2 > xClient) { x2 -= x2d; negd( x2d ); x2 += x2d; }
  168.         if (y1 < 0 || y1 > yClient) { y1 -= y1d; negd( y1d ); y1 += y1d; }
  169.         if (y2 < 0 || y2 > yClient) { y2 -= y2d; negd( y2d ); y2 += y2d; }
  170.  
  171.         // spin as needed
  172.         if (bSpin)
  173.         {
  174.             INT nDx = x2 - x1, nDy = y2 - y1;
  175.             INT dx = ((nDx < 0) ? -nDx : nDx);
  176.             INT dy = ((nDy < 0) ? -nDy : nDy);
  177.             INT nDist = dx + dy - (((dx > dy) ? dy : dx) >> 1);
  178.             if (nDist > 1)
  179.             {
  180.                 INT ddx = nDx * 2 / nDist;
  181.                 INT ddy = nDy * 2 / nDist;
  182.                 x1d += ddx, x2d -= ddx;
  183.                 y1d += ddy, y2d -= ddy;
  184.             }
  185.         }
  186.  
  187.         // change the colors one component at a time
  188.         t = arand( 3 );
  189.         rgbC[t] += rgbCd[t];
  190.         if (rgbC[t] < 0 || rgbC[t] > 255)
  191.         {
  192.             rgbC[t] -= rgbCd[t];
  193.             negd( rgbCd[t] );
  194.             rgbC[t] += rgbCd[t];
  195.         }
  196.  
  197.         // put the color into the current palette entry
  198.         PalEntry.peRed = (BYTE)nR;
  199.         PalEntry.peGreen = (BYTE)nG;
  200.         PalEntry.peBlue = (BYTE)nB;
  201.         PalEntry.peFlags = PC_RESERVED;
  202.         RealizePalette( hdc );
  203.         AnimatePalette( hAppPalette, nCurPalEntry, 1, &PalEntry );
  204.  
  205.         if (bSolid)
  206.         {
  207.             HBRUSH      hBrush;
  208.  
  209.             hBrush = CreateSolidBrush( PALETTEINDEX(nCurPalEntry) );
  210.             hBrush = SelectObject( hdc, hBrush );
  211.             SelectObject( hdc, GetStockObject( NULL_PEN ) );
  212.             SetPolyFillMode( hdc, ALTERNATE );
  213.             Polygon( hdc, Pt, 4 );
  214.             hBrush = SelectObject( hdc, hBrush );
  215.             DeleteObject( hBrush );
  216.         }
  217.         else // line segments
  218.         {
  219.             HPEN        hPen;
  220.  
  221.             hPen = CreatePen( PS_SOLID, 0, PALETTEINDEX(nCurPalEntry) );
  222.             hPen = SelectObject( hdc, hPen );
  223.             MoveTo( hdc, x1, y1 );
  224.             LineTo( hdc, x2, y2 );
  225.             hPen = SelectObject( hdc, hPen );
  226.             DeleteObject( hPen );
  227.         }
  228.  
  229.         // use the next palette entry next time
  230.         if (++nCurPalEntry >= nColorCnt) nCurPalEntry = 0;
  231.     }
  232.  
  233.     DeleteObject( SelectPalette( hdc, hOldPalette, FALSE ) );
  234. }
  235.